﻿using System;
using System.IO;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
namespace MouseKeyboard
{
    // 键盘码数据
    public struct TMKKeyData
    {
        public TMKKeyCode Code;
        // 键码
        public char[] __Char;
        // 键码对应的字符
        public byte Length;
        // 高4位为通码长度，低4位为断码长度
        public byte[] Make;
        // 通码
        public byte[] __Break;
    } // end TMKKeyData

    // 104键盘代码，注：“Pause”键被忽略
    public enum TMKKeyCode
    {
        kcA,
        kcB,
        kcC,
        kcD,
        kcE,
        kcF,
        kcG,
        kcH,
        kcI,
        kcJ,
        kcK,
        kcL,
        kcM,
        kcN,
        kcO,
        kcP,
        kcQ,
        kcR,
        kcS,
        kcT,
        kcU,
        kcV,
        kcW,
        kcX,
        kcY,
        kcZ,
        kc0,
        kc1,
        kc2,
        kc3,
        kc4,
        kc5,
        kc6,
        kc7,
        kc8,
        kc9,
        kc_C0,
        kc_BD,
        kc_BB,
        kc_DC,
        kc_DB,
        kc_DD,
        kc_BA,
        kc_DE,
        kc_BC,
        kc_BE,
        kc_BF,
        kcBack,
        kcSpace,
        kcTab,
        kcCaps,
        kcLShift,
        kcLCtrl,
        kcLWin,
        kcLAlt,
        kcRShift,
        kcRCtrl,
        kcRWin,
        kcRAlt,
        kcApps,
        kcEnter,
        kcEsc,
        kcF1,
        kcF2,
        kcF3,
        kcF4,
        kcF5,
        kcF6,
        kcF7,
        kcF8,
        kcF9,
        kcF10,
        kcF11,
        kcF12,
        kcSysRq,
        kcScroll,
        kcPause,
        kcInsert,
        kcHome,
        kcPageUp,
        kcDelete,
        kcEnd,
        kcPageDown,
        kcUp,
        kcLeft,
        kcDown,
        kcRight,
        kcNum,
        kcNumDivide,
        kcNumMultiply,
        kcNumSubtract,
        kcNumAdd,
        kcNumEnter,
        kcNumDecimal,
        kcNum0,
        kcNum1,
        kcNum2,
        kcNum3,
        kcNum4,
        kcNum5,
        kcNum6,
        kcNum7,
        kcNum8,
        kcNum9
    } // end TMKKeyCode

    // 第一套键盘扫描码，101、102和104键的键盘，注：“Pause”键被忽略。
    // 断码$19改为$90
    // 鼠标代码
    public enum TMKMouseCode
    {
        mcLeft,
        mcMiddle,
        mcRight
    } // end TMKMouseCode

    // 数据包类型
    public enum TMKDataType
    {
        dtMouse,
        dtKey
    } // end TMKDataType

}

namespace MouseKeyboard.Units
{
    public class MouseKeyboard
    {
        public static bool MKInitAlready = false;
        // 是否经过初始化
        public static int MKPacketLength = 0;
        // 鼠标数据包长度
        public static bool[] MKButtons = new bool[Convert.ToInt32(TMKMouseCode.mcRight) + 1];
        // 鼠标键是否按下
        public static int[] MKConversion;
        // 第一套键盘扫描码，101、102和104键的键盘，注：“Pause”键被忽略。
        public const int MKKeyCount = 104;
        // 断码$19改为$90
        public static TMKKeyData[] MKKeyData = {
    {TMKKeyCode.kcA, "aA", 0x11, {0x1E, 0x00, 0x00, 0x00}, {0x9E, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcB, "bB", 0x11, {0x30, 0x00, 0x00, 0x00}, {0xB0, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcC, "cC", 0x11, {0x2E, 0x00, 0x00, 0x00}, {0xAE, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcD, "dD", 0x11, {0x20, 0x00, 0x00, 0x00}, {0xA0, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcE, "eE", 0x11, {0x12, 0x00, 0x00, 0x00}, {0x92, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF, "fF", 0x11, {0x21, 0x00, 0x00, 0x00}, {0xA1, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcG, "gG", 0x11, {0x22, 0x00, 0x00, 0x00}, {0xA2, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcH, "hH", 0x11, {0x23, 0x00, 0x00, 0x00}, {0xA3, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcI, "iI", 0x11, {0x17, 0x00, 0x00, 0x00}, {0x97, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcJ, "jJ", 0x11, {0x24, 0x00, 0x00, 0x00}, {0xA4, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcK, "kK", 0x11, {0x25, 0x00, 0x00, 0x00}, {0xA5, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcL, "lL", 0x11, {0x26, 0x00, 0x00, 0x00}, {0xA6, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcM, "mM", 0x11, {0x32, 0x00, 0x00, 0x00}, {0xB2, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcN, "nN", 0x11, {0x31, 0x00, 0x00, 0x00}, {0xB1, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcO, "oO", 0x11, {0x18, 0x00, 0x00, 0x00}, {0x98, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcP, "pP", 0x11, {0x19, 0x00, 0x00, 0x00}, {0x99, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcQ, "qQ", 0x11, {0x10, 0x00, 0x00, 0x00}, {0x90, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcR, "rR", 0x11, {0x13, 0x00, 0x00, 0x00}, {0x93, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcS, "sS", 0x11, {0x1F, 0x00, 0x00, 0x00}, {0x9F, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcT, "tT", 0x11, {0x14, 0x00, 0x00, 0x00}, {0x94, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcU, "uU", 0x11, {0x16, 0x00, 0x00, 0x00}, {0x96, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcV, "vV", 0x11, {0x2F, 0x00, 0x00, 0x00}, {0xAF, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcW, "wW", 0x11, {0x11, 0x00, 0x00, 0x00}, {0x91, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcX, "xX", 0x11, {0x2D, 0x00, 0x00, 0x00}, {0xAD, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcY, "yY", 0x11, {0x15, 0x00, 0x00, 0x00}, {0x95, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcZ, "zZ", 0x11, {0x2C, 0x00, 0x00, 0x00}, {0xAC, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc0, "0)", 0x11, {0x0B, 0x00, 0x00, 0x00}, {0x8B, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc1, "1!", 0x11, {0x02, 0x00, 0x00, 0x00}, {0x82, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc2, "2@", 0x11, {0x03, 0x00, 0x00, 0x00}, {0x83, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc3, "3#", 0x11, {0x04, 0x00, 0x00, 0x00}, {0x84, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc4, "4$", 0x11, {0x05, 0x00, 0x00, 0x00}, {0x85, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc5, "5%", 0x11, {0x06, 0x00, 0x00, 0x00}, {0x86, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc6, "6^", 0x11, {0x07, 0x00, 0x00, 0x00}, {0x87, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc7, "7&", 0x11, {0x08, 0x00, 0x00, 0x00}, {0x88, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc8, "8*", 0x11, {0x09, 0x00, 0x00, 0x00}, {0x89, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc9, "9(", 0x11, {0x0A, 0x00, 0x00, 0x00}, {0x8A, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_C0, "`~", 0x11, {0x29, 0x00, 0x00, 0x00}, {0x89, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_BD, "-_", 0x11, {0x0C, 0x00, 0x00, 0x00}, {0x8C, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_BB, "=+", 0x11, {0x0D, 0x00, 0x00, 0x00}, {0x8D, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_DC, "\\|", 0x11, {0x2B, 0x00, 0x00, 0x00}, {0xAB, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_DB, "[{", 0x11, {0x1A, 0x00, 0x00, 0x00}, {0x9A, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_DD, "]}", 0x11, {0x1B, 0x00, 0x00, 0x00}, {0x9B, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_BA, ";:", 0x11, {0x27, 0x00, 0x00, 0x00}, {0xA7, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_DE, '\'' + '\"', 0x11, {0x28, 0x00, 0x00, 0x00}, {0xA8, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_BC, ",<", 0x11, {0x33, 0x00, 0x00, 0x00}, {0xB3, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_BE, ".>", 0x11, {0x34, 0x00, 0x00, 0x00}, {0xB4, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kc_BF, "/?", 0x11, {0x35, 0x00, 0x00, 0x00}, {0xB5, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcBack, "\0\0", 0x11, {0x0E, 0x00, 0x00, 0x00}, {0x8E, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcSpace, ' ' + '\0', 0x11, {0x39, 0x00, 0x00, 0x00}, {0xB9, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcTab, "\09\0", 0x11, {0x0F, 0x00, 0x00, 0x00}, {0x8F, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcCaps, "\0\0", 0x11, {0x3A, 0x00, 0x00, 0x00}, {0xBA, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcLShift, "\0\0", 0x11, {0x2A, 0x00, 0x00, 0x00}, {0xAA, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcLCtrl, "\0\0", 0x11, {0x1D, 0x00, 0x00, 0x00}, {0x9D, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcLWin, "\0\0", 0x22, {0xE0, 0x5B, 0x00, 0x00}, {0xE0, 0xDB, 0x00, 0x00}} , 
    {TMKKeyCode.kcLAlt, "\0\0", 0x11, {0x38, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcRShift, "\0\0", 0x11, {0x36, 0x00, 0x00, 0x00}, {0xB6, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcRCtrl, "\0\0", 0x22, {0xE0, 0x1D, 0x00, 0x00}, {0xE0, 0x9D, 0x00, 0x00}} , 
    {TMKKeyCode.kcRWin, "\0\0", 0x22, {0xE0, 0x5C, 0x00, 0x00}, {0xE0, 0xDC, 0x00, 0x00}} , 
    {TMKKeyCode.kcRAlt, "\0\0", 0x22, {0xE0, 0x38, 0x00, 0x00}, {0xE0, 0xB8, 0x00, 0x00}} , 
    {TMKKeyCode.kcApps, "\0\0", 0x22, {0xE0, 0x5D, 0x00, 0x00}, {0xE0, 0xDD, 0x00, 0x00}} , 
    {TMKKeyCode.kcEnter, "\r\0", 0x11, {0x1C, 0x00, 0x00, 0x00}, {0x9C, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcEsc, "\0\0", 0x11, {0x01, 0x00, 0x00, 0x00}, {0x81, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF1, "\0\0", 0x11, {0x3B, 0x00, 0x00, 0x00}, {0xBB, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF2, "\0\0", 0x11, {0x3C, 0x00, 0x00, 0x00}, {0xBC, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF3, "\0\0", 0x11, {0x3D, 0x00, 0x00, 0x00}, {0xBD, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF4, "\0\0", 0x11, {0x3E, 0x00, 0x00, 0x00}, {0xBE, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF5, "\0\0", 0x11, {0x3F, 0x00, 0x00, 0x00}, {0xBF, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF6, "\0\0", 0x11, {0x40, 0x00, 0x00, 0x00}, {0xC0, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF7, "\0\0", 0x11, {0x41, 0x00, 0x00, 0x00}, {0xC1, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF8, "\0\0", 0x11, {0x42, 0x00, 0x00, 0x00}, {0xC2, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF9, "\0\0", 0x11, {0x43, 0x00, 0x00, 0x00}, {0xC3, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF10, "\0\0", 0x11, {0x44, 0x00, 0x00, 0x00}, {0xC4, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF11, "\0\0", 0x11, {0x57, 0x00, 0x00, 0x00}, {0xD7, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcF12, "\0\0", 0x11, {0x58, 0x00, 0x00, 0x00}, {0xD8, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcSysRq, "\0\0", 0x44, {0xE0, 0x2A, 0xE0, 0x37}, {0xE0, 0xB7, 0xE0, 0xAA}} , 
    {TMKKeyCode.kcScroll, "\0\0", 0x11, {0x46, 0x00, 0x00, 0x00}, {0xC6, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcPause, "\0\0", 0x33, {0xE1, 0x1D, 0x45, 0x00}, {0xE1, 0x9D, 0xC5, 0x00}} , 
    {TMKKeyCode.kcInsert, "\0\0", 0x22, {0xE0, 0x52, 0x00, 0x00}, {0xE0, 0xD2, 0x00, 0x00}} , 
    {TMKKeyCode.kcHome, "\0\0", 0x22, {0xE0, 0x47, 0x00, 0x00}, {0xE0, 0x97, 0x00, 0x00}} , 
    {TMKKeyCode.kcPageUp, "\0\0", 0x22, {0xE0, 0x49, 0x00, 0x00}, {0xE0, 0xC9, 0x00, 0x00}} , 
    {TMKKeyCode.kcDelete, "\0\0", 0x22, {0xE0, 0x53, 0x00, 0x00}, {0xE0, 0xD3, 0x00, 0x00}} , 
    {TMKKeyCode.kcEnd, "\0\0", 0x22, {0xE0, 0x4F, 0x00, 0x00}, {0xE0, 0xCF, 0x00, 0x00}} , 
    {TMKKeyCode.kcPageDown, "\0\0", 0x22, {0xE0, 0x51, 0x00, 0x00}, {0xE0, 0xD1, 0x00, 0x00}} , 
    {TMKKeyCode.kcUp, "\0\0", 0x22, {0xE0, 0x48, 0x00, 0x00}, {0xE0, 0xC8, 0x00, 0x00}} , 
    {TMKKeyCode.kcLeft, "\0\0", 0x22, {0xE0, 0x4B, 0x00, 0x00}, {0xE0, 0xCB, 0x00, 0x00}} , 
    {TMKKeyCode.kcDown, "\0\0", 0x22, {0xE0, 0x50, 0x00, 0x00}, {0xE0, 0xD0, 0x00, 0x00}} , 
    {TMKKeyCode.kcRight, "\0\0", 0x22, {0xE0, 0x4D, 0x00, 0x00}, {0xE0, 0xCD, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum, "\0\0", 0x11, {0x45, 0x00, 0x00, 0x00}, {0xC5, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNumDivide, "\0\0", 0x22, {0xE0, 0x35, 0x00, 0x00}, {0xE0, 0xB5, 0x00, 0x00}} , 
    {TMKKeyCode.kcNumMultiply, "\0\0", 0x11, {0x37, 0x00, 0x00, 0x00}, {0xB7, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNumSubtract, "\0\0", 0x11, {0x4A, 0x00, 0x00, 0x00}, {0xCA, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNumAdd, "\0\0", 0x11, {0x4E, 0x00, 0x00, 0x00}, {0xCE, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNumEnter, "\0\0", 0x22, {0xE0, 0x1C, 0x00, 0x00}, {0xE0, 0x9C, 0x00, 0x00}} , 
    {TMKKeyCode.kcNumDecimal, "\0\0", 0x11, {0x53, 0x00, 0x00, 0x00}, {0xD3, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum0, "\0\0", 0x11, {0x52, 0x00, 0x00, 0x00}, {0xD2, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum1, "\0\0", 0x11, {0x4F, 0x00, 0x00, 0x00}, {0xCF, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum2, "\0\0", 0x11, {0x50, 0x00, 0x00, 0x00}, {0xD0, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum3, "\0\0", 0x11, {0x51, 0x00, 0x00, 0x00}, {0xD1, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum4, "\0\0", 0x11, {0x4B, 0x00, 0x00, 0x00}, {0xCB, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum5, "\0\0", 0x11, {0x4C, 0x00, 0x00, 0x00}, {0xCC, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum6, "\0\0", 0x11, {0x4D, 0x00, 0x00, 0x00}, {0xCD, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum7, "\0\0", 0x11, {0x47, 0x00, 0x00, 0x00}, {0xC7, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum8, "\0\0", 0x11, {0x48, 0x00, 0x00, 0x00}, {0xC8, 0x00, 0x00, 0x00}} , 
    {TMKKeyCode.kcNum9, "\0\0", 0x11, {0x49, 0x00, 0x00, 0x00}, {0xC9, 0x00, 0x00, 0x00}} };
        [DllImport("WinIo.dll")]
        public static extern bool InitializeWinIo();

        [DllImport("WinIo.dll")]
        public static extern void ShutdownWinIo();

        // 功能函数
        public static bool MKInitMouseKey()
        {
            bool result;
            FileStream IniFile;
            result = InitializeWinIo();
            MKInitAlready = result;
            if (!result)
            {
                return result;
            }
            //@ Undeclared identifier(3): 'SM_CMOUSEBUTTONS'
            //@ Undeclared identifier(3): 'SM_MOUSEWHEELPRESENT'
            if ((GetSystemMetrics(SM_CMOUSEBUTTONS) >= 5) || (GetSystemMetrics(SM_MOUSEWHEELPRESENT) != 0))
            {
                MKPacketLength = 4;
            }
            else
            {
                MKPacketLength = 3;
            }
            MKButtons[TMKMouseCode.mcLeft] = false;
            MKButtons[TMKMouseCode.mcMiddle] = false;
            MKButtons[TMKMouseCode.mcRight] = false;
            IniFile = new FileStream(Environment.CurrentDirectory + "\\Mouse.ini");
            if (!MKConversionFromIni(ref MKConversion, IniFile, "Conversion"))
            {
                MKInitConversion(ref MKConversion);
            }
            //@ Unsupported property or method(C): 'Free'
            IniFile.Free;
            return result;
        }

        // 释放驱动程序
        public static void MKFreeMouseKey()
        {
            if (!MKInitAlready)
            {
                ShutdownWinIo();
            }
            MKInitAlready = false;
        }

        public void MKSendData_fSetByte(byte Por, byte Cod)
        {
            Thread.CurrentThread.Sleep(1);
            // asm
            // PUSH EAX
            // PUSH EDX
            // //等待状态寄存器标志位OBF置0
            // @Loop:
            // IN  AL,$64
            // AND AL,01b
            // JNZ @Loop
            // //写入数据
            // MOV AL,Cod
            // MOV DL,Por
            // MOV DH,0
            // OUT DX,AL
            // 
            // POP EDX
            // POP EAX
            // end

        }

        // 向指定的键盘鼠标端口发送数据包，返回是否成功，
        // Len为数据包的字节长度。
        public static bool MKSendData(byte[] Data, byte Len, TMKDataType Typ)
        {
            bool result;
            byte i;
            byte b;
            if (!MKInitAlready)
            {
                result = MKInitMouseKey();
                if (!result)
                {
                    return result;
                }
            }
            if (Typ == TMKDataType.dtMouse)
            {
                b = 0xD3;
            }
            else
            {
                b = 0xD2;
            }
            for (i = 0; i < Len; i++)
            {
                MKSendData_fSetByte(0x64, b);
                MKSendData_fSetByte(0x60, Data[i]);
            }
            result = true;
            return result;
        }

        // 查找指定键码在MKKeyData中的id，找到返回id，没找到返回-1。
        public static int MKFindKeyCode(TMKKeyCode Code)
        {
            int result;
            int i;
            for (i = 0; i < MKKeyCount; i++)
            {
                if (MKKeyData[i].Code == Code)
                {
                    break;
                }
            }
            if (i < MKKeyCount)
            {
                result = i;
            }
            else
            {
                result = -1;
            }
            return result;
        }

        // 查找指定字符在MKKeyData中的id，找到返回id，没找到返回-1。
        public static int MKFindKeyChar(char __Char)
        {
            int result;
            int i;
            for (i = 0; i < MKKeyCount; i++)
            {
                if ((MKKeyData[i].__Char[0] == __Char) || (MKKeyData[i].__Char[1] == __Char))
                {
                    break;
                }
            }
            if (i < MKKeyCount)
            {
                result = i;
            }
            else
            {
                result = -1;
            }
            return result;
        }

        // 按下指定的键，返回是否成功。
        public static bool MKKeyDown(TMKKeyCode Code)
        {
            bool result;
            int id;
            id = MKFindKeyCode(Code);
            if (id == -1)
            {
                result = false;
                return result;
            }
            result = MKSendData(MKKeyData[id].Make, MKKeyData[id].Length >> 4, TMKDataType.dtKey);
            return result;
        }

        // 放开指定的键，返回是否成功。
        public static bool MKKeyUp(TMKKeyCode Code)
        {
            bool result;
            int id;
            id = MKFindKeyCode(Code);
            if (id == -1)
            {
                result = false;
                return result;
            }
            result = MKSendData(MKKeyData[id].__Break, MKKeyData[id].Length & 0xF, TMKDataType.dtKey);
            return result;
        }

        // 按下并放开指定的键，返回是否成功，
        // Interval为按下和放开之间的时间间隔。
        public static bool MKKeyPress(TMKKeyCode Code, uint Interval)
        {
            bool result;
            int id;
            id = MKFindKeyCode(Code);
            if (id == -1)
            {
                result = false;
                return result;
            }
            result = MKSendData(MKKeyData[id].Make, MKKeyData[id].Length >> 4, TMKDataType.dtKey);
            if (!result)
            {
                return result;
            }
            if (Interval != 0)
            {
                Thread.CurrentThread.Sleep(Interval);
            }
            result = MKSendData(MKKeyData[id].__Break, MKKeyData[id].Length & 0xF, TMKDataType.dtKey);
            return result;
        }

        // 模拟键盘输入指定的文本，返回是否成功，
        // 文本中只能是单字节字符（#32~#126）、Tab（#9）键和回车键（#13），
        // 其它字符会被忽略，Interval为按下和放开键之间的时间间隔。
        public static bool MKKeyInput(string Text, uint Interval)
        {
            bool result;
            bool CapsState;
            bool NeedShift;
            int i;
            int id;
            int idShift;
            //@ Undeclared identifier(3): 'VK_CAPITAL'
            //@ Unsupported function or procedure: 'GetKeyState'
            CapsState = ((GetKeyState(VK_CAPITAL) & 1) != 0);
            idShift = MKFindKeyCode(TMKKeyCode.kcLShift);
            if (idShift == -1)
            {
                result = false;
                return result;
            }
            result = true;
            for (i = 1; i <= Text.Length; i++)
            {
                id = MKFindKeyChar(Text[i]);
                if (id == -1)
                {
                    continue;
                }
                NeedShift = (MKKeyData[id].__Char[1] == Text[i]);
                if ((MKKeyData[id].__Char[0] >= 'a') && (MKKeyData[id].__Char[0] <= 'z') && CapsState)
                {
                    NeedShift = !NeedShift;
                }
                // 按下上档键
                if (NeedShift)
                {
                    result = MKSendData(MKKeyData[idShift].Make, MKKeyData[idShift].Length >> 4, TMKDataType.dtKey);
                    if (!result)
                    {
                        break;
                    }
                    if (Interval != 0)
                    {
                        Thread.CurrentThread.Sleep(Interval);
                    }
                }
                // 按下指定键
                result = MKSendData(MKKeyData[id].Make, MKKeyData[id].Length >> 4, TMKDataType.dtKey);
                if (!result)
                {
                    break;
                }
                if (Interval != 0)
                {
                    Thread.CurrentThread.Sleep(Interval);
                }
                // 放开指定键
                result = MKSendData(MKKeyData[id].__Break, MKKeyData[id].Length & 0xF, TMKDataType.dtKey);
                if (!result)
                {
                    break;
                }
                if (Interval != 0)
                {
                    Thread.CurrentThread.Sleep(Interval);
                }
                // 放开上档键
                if (NeedShift)
                {
                    result = MKSendData(MKKeyData[idShift].__Break, MKKeyData[idShift].Length & 0xF, TMKDataType.dtKey);
                    if (!result)
                    {
                        break;
                    }
                    if (Interval != 0)
                    {
                        Thread.CurrentThread.Sleep(Interval);
                    }
                }
            }
            return result;
        }

        // 按指定参数初始化一个鼠标数据包。
        // 注：以下三个值为鼠标位移计数器的值，非象素值，
        // cX为鼠标左右移位值，cY为鼠标上下移位值，cZ为鼠标滚轮滚动移位值。
        public static void MKInitMouseData(ref byte[] Data, int cX, int cY, int cZ)
        {
            byte[] ByteBit = { 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5 };
            Data[0] = ByteBit[3];
            if (MKButtons[TMKMouseCode.mcLeft])
            {
                Data[0] = Data[0] || ByteBit[0];
            }
            if (MKButtons[TMKMouseCode.mcRight])
            {
                Data[0] = Data[0] || ByteBit[1];
            }
            if (MKButtons[TMKMouseCode.mcMiddle])
            {
                Data[0] = Data[0] || ByteBit[2];
            }
            if (cX < 0)
            {
                Data[0] = Data[0] || ByteBit[4];
            }
            if (cY < 0)
            {
                Data[0] = Data[0] || ByteBit[5];
            }
            Data[1] = ((byte)cX & 0xFF);
            Data[2] = ((byte)cY & 0xFF);
            if (MKPacketLength == 4)
            {
                Data[3] = ((byte)cZ & 0xF);
            }
            else
            {
                Data[3] = 0;
            }
        }

        // 按下鼠标的指定键，返回是否成功。
        public static bool MKMouseDown(TMKMouseCode Code)
        {
            bool result;
            byte[] Data;
            MKButtons[Code] = true;
            MKInitMouseData(ref Data, 0, 0, 0);
            result = MKSendData(Data, MKPacketLength, TMKDataType.dtMouse);
            return result;
        }

        // 放开鼠标的指定键，返回是否成功。
        public static bool MKMouseUp(TMKMouseCode Code)
        {
            bool result;
            byte[] Data;
            MKButtons[Code] = false;
            MKInitMouseData(ref Data, 0, 0, 0);
            result = MKSendData(Data, MKPacketLength, TMKDataType.dtMouse);
            return result;
        }

        // 单击鼠标的指定键，返回是否成功，
        // Interval为按下和放开键之间的时间间隔。
        public static bool MKMouseClick(TMKMouseCode Code, uint Interval)
        {
            bool result;
            byte[] Data;
            result = false;
            MKButtons[Code] = true;
            MKInitMouseData(ref Data, 0, 0, 0);
            if (!MKSendData(Data, MKPacketLength, TMKDataType.dtMouse))
            {
                return result;
            }
            if (Interval != 0)
            {
                Thread.CurrentThread.Sleep(Interval);
            }
            MKButtons[Code] = false;
            MKInitMouseData(ref Data, 0, 0, 0);
            if (!MKSendData(Data, MKPacketLength, TMKDataType.dtMouse))
            {
                return result;
            }
            result = true;
            return result;
        }

        // 滚动鼠标的滚轮，返回是否成功。
        // 注：cZ为鼠标滚轮滚动移位值，非象素值，cZ有效值的范围在-8到+7，
        // cZ<0：向上滚动，cZ>0向下滚动
        public static bool MKMouseWheel(int cZ)
        {
            bool result;
            byte[] Data;
            MKInitMouseData(ref Data, 0, 0, cZ);
            result = MKSendData(Data, MKPacketLength, TMKDataType.dtMouse);
            return result;
        }

        // 移动鼠标指针在屏幕上的位置，返回是否成功，
        // cX<0：向左移动，cX>0：向右移动，cY<0：向下移动，cY>0：向上移动，
        // 注：cX和cY为鼠标位移计数器的值，非象素值，
        // cX和cY的值的范围是-255到+255。
        public static bool MKMouseMove(int cX, int cY)
        {
            bool result;
            byte[] Data;
            MKInitMouseData(ref Data, cX, cY, 0);
            result = MKSendData(Data, MKPacketLength, TMKDataType.dtMouse);
            return result;
        }

        // 初始化一个鼠标移动换算表，假设鼠标的灵敏度设为中等。
        public static void MKInitConversion(ref int[] Con)
        {
            int i;
            for (i = 1; i <= 6; i++)
            {
                Con[i] = i;
            }
            for (i = 7; i <= 255; i++)
            {
                Con[i] = i * 2;
            }
        }

        // 测试并确认鼠标移动换算表，返回是否成功。
        // MaxMove为测试时的鼠标移动的最大值。
        public static bool MKTestConversion(ref int[] Con, int MaxMove)
        {
            bool result;
            Point p;
            int i;
            int Width;
            int Height;
            if (MaxMove <= 0)
            {
                MaxMove = 0x7FFFFFFF;
            }
            //@ Undeclared identifier(3): 'SM_CXSCREEN'
            Width = GetSystemMetrics(SM_CXSCREEN) - 1;
            //@ Undeclared identifier(3): 'SM_CYSCREEN'
            Height = GetSystemMetrics(SM_CYSCREEN) - 1;
            for (i = 1; i <= 255; i++)
            {
                //@ Unsupported function or procedure: 'SetCursorPos'
                SetCursorPos(0, Height);
                result = MKMouseMove(i, i);
                if (!result)
                {
                    break;
                }
                Thread.CurrentThread.Sleep(50);
                //@ Unsupported function or procedure: 'GetCursorPos'
                GetCursorPos(p);
                if ((p.X <= 0) || (p.X >= Width) || (p.X <= 0) || (p.X >= Height))
                {
                    Con[i] = 0;
                }
                else
                {
                    Con[i] = (p.X + (Height - p.X)) / 2;
                }
                if (Con[i] > MaxMove)
                {
                    break;
                }
            }
            if (i < 255)
            {
                for (i = i; i <= 255; i++)
                {
                    Con[i] = 0;
                }
            }
            return result;
        }

        // 将鼠标移动换算表导出到INI文件的指定节中，返回是否成功。
        public static bool MKConversionToIni(int[] Con, FileStream IniFile, string Section)
        {
            bool result;
            int i;
            if ((IniFile == null) || (Section.Length == 0))
            {
                result = false;
                return result;
            }
            for (i = 1; i <= 255; i++)
            {
                if (Con[i] != 0)
                {
                    //@ Unsupported function or procedure: 'Format'
                    //@ Unsupported function or procedure: 'Format'
                    //@ Unsupported property or method(A): 'WriteString'
                    IniFile.WriteString(Section, Format("%d", new int[] { i }), Format("%d", new int[] { Con[i] }));
                }
            }
            result = true;
            return result;
        }

        // 从INI文件的指定节中导入鼠标移动换算表，返回是否成功。
        public static bool MKConversionFromIni(ref int[] Con, FileStream IniFile, string Section)
        {
            bool result;
            int i;
            if ((IniFile == null) || (Section.Length == 0))
            {
                result = false;
                return result;
            }
            result = false;
            for (i = 1; i <= 255; i++)
            {
                //@ Unsupported function or procedure: 'Format'
                //@ Unsupported property or method(A): 'ReadInteger'
                Con[i] = IniFile.ReadInteger(Section, Format("%d", new int[] { i }), 0);
                if (!result)
                {
                    result = (Con[i] != 0);
                }
            }
            return result;
        }

        // 导入一个鼠标移动换算表作为默认换算表。
        public static void MKLoadConversion(int[] Con)
        {
            int i;
            for (i = 1; i <= 255; i++)
            {
                MKConversion[i] = Con[i];
            }
        }

        // 利用鼠标移动换算表计算移动量
        public int MKMouseMoveTo_fConversion(ref int dis)
        {
            int result;
            int fi;
            int fn;
            result = 0;
            if (dis == 0)
            {
                return result;
            }
            fn = Math.Abs(dis);
            if (fn > MaxMove)
            {
                fn = MaxMove;
            }
            for (fi = 1; fi <= 255; fi++)
            {
                if (Con[fi] > fn)
                {
                    break;
                }
                if (Con[fi] != 0)
                {
                    result = fi;
                }
            }
            if (result == 0)
            {
                result = 1;
                fn = 1;
            }
            else
            {
                fn = Con[result];
            }
            if (dis < 0)
            {
                dis = -fn;
                result = -result;
            }
            else
            {
                dis = fn;
            }
            return result;
        }

        // 将鼠标指针移动到指定位置，返回是否成功，
        // 注：X和Y为象素值，X和Y的值的范围不能超出屏幕，
        // MaxMove为移动时的cX和cY的最大值，
        // Interval为两次移动之间的时间间隔，
        // 使用指定的鼠标移动换算表Con进行移动坐标的计算。
        public static bool MKMouseMoveTo(int X, int Y, int[] Con, int MaxMove, uint Interval)
        {
            bool result;
            Point p;
            int cX;
            int cY;
            int n;
            bool inLeft;
            bool inTop;
            result = true;
            if (MaxMove <= 0)
            {
                MaxMove = 0x7FFFFFFF;
            }
            //@ Undeclared identifier(3): 'SM_CXSCREEN'
            p.X = GetSystemMetrics(SM_CXSCREEN) - 1;
            if (X > p.X)
            {
                X = p.X;
            }
            //@ Undeclared identifier(3): 'SM_CYSCREEN'
            p.X = GetSystemMetrics(SM_CYSCREEN) - 1;
            if (Y > p.X)
            {
                Y = p.X;
            }
            //@ Unsupported function or procedure: 'GetCursorPos'
            GetCursorPos(p);
            inLeft = (p.X < X);
            inTop = (p.X < Y);
            while (!((((p.X < X) != inLeft) || (p.X == X)) && (((p.X < Y) != inTop) || (p.X == Y))))
            {
                n = X - p.X;
                cX = MKMouseMoveTo_fConversion(ref n);
                p.X = p.X + n;
                n = Y - p.X;
                cY = -MKMouseMoveTo_fConversion(ref n);
                p.X = p.X + n;
                result = MKMouseMove(cX, cY);
                if (!result)
                {
                    return result;
                }
                if (Interval != 0)
                {
                    Thread.CurrentThread.Sleep(Interval);
                }
            }
            return result;
        }

        // 将鼠标指针移动到指定位置，返回是否成功，
        // 注：X和Y为象素值，X和Y的值的范围不能超出屏幕，
        // MaxMove为移动时的cX和cY的最大值，
        // Interval为两次移动之间的时间间隔，
        // 使用默认的鼠标移动换算表进行移动坐标的计算。
        public static bool MKMouseMoveTo(int X, int Y, int MaxMove, uint Interval)
        {
            bool result;
            result = MKMouseMoveTo(X, Y, MKConversion, MaxMove, Interval);
            return result;
        }

        public void initialization()
        {
            MKInitMouseKey();
        }

        public void finalization()
        {
            MKFreeMouseKey();
        }

    } // end MouseKeyboard

}

